﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;

namespace Project32CHE.Web.Contexts
{
    public static class DomainContext
    {
        private static string[] LocalHosts = new string[] { /*".66km.com"*/ };
        private static string BasePath = "domains";
        private static string ConfigFile = "custom.json";
        private static Encoding FileEncoding = Encoding.UTF8;
        private class DomainConfig
        {
            public string Name { get; set; }
            public string Title { get; set; }
            public string ScriptFile { get; set; }
            public string CssFile { get; set; }
            public Dictionary<string, string> ViewData { get; set; }
            public DomainConfig()
            {
                this.Name = "66公里";
                this.Title = "66公里汽修管理系统";
                this.ScriptFile = "custom.js";
                this.CssFile = "custom.css";
                this.ViewData = new Dictionary<string, string>();
            }
        }
        private class DomainHelper
        {
            private Uri Url { get; set; }

            internal DomainHelper(Uri url)
            {
                this.Url = url;
            }

            private bool? isLocal = null;
            public bool IsLocal
            {
                get
                {
                    if (!this.isLocal.HasValue)
                    {
                        var domain = this.Url.DnsSafeHost;
                        var b = LocalHosts.Any(x => domain.EndsWith(x, StringComparison.OrdinalIgnoreCase));
                        this.isLocal = b;
                    }
                    return this.isLocal.Value;
                }
            }

            private string domainPath = null;
            public string DomainPath
            {
                get
                {
                    if (this.domainPath == null)
                    {
                        var path = string.Empty;
                        var phyPath = this.PhysicalPath;
                        if (!string.IsNullOrWhiteSpace(phyPath))
                        {
                            var domain = this.Url.DnsSafeHost;
                            path = "/" + BasePath + "/" + domain;
                        }
                        this.domainPath = path;
                    }
                    return this.domainPath;
                }
            }

            private string physicalPath = null;
            public string PhysicalPath
            {
                get
                {
                    if (this.physicalPath == null)
                    {
                        var path = string.Empty;
                        var domain = this.Url.DnsSafeHost;
                        var phyPath = Path.Combine(HttpRuntime.AppDomainAppPath, BasePath, domain);
                        if (Directory.Exists(phyPath))
                        {
                            path = phyPath;
                        }
                        this.physicalPath = path;
                    }
                    return this.physicalPath;
                }
            }

            private DomainConfig config = null;
            public DomainConfig Config
            {
                get
                {
                    if (this.config == null)
                    {
                        var path = this.PhysicalPath;
                        var file = ConfigFile;
                        if (!string.IsNullOrWhiteSpace(path))
                        {
                            var filePath = Path.Combine(path, file);
                            var fileContent = string.Empty;
                            if (File.Exists(filePath))
                            {
                                using (var f = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
                                {
                                    using (var fr = new StreamReader(f, FileEncoding))
                                    {
                                        fileContent = fr.ReadToEnd();
                                    }
                                }
                            }
                            if (!string.IsNullOrWhiteSpace(fileContent))
                            {
                                //this.config = JsonUtility.FromJson<DomainConfig>(fileContent);
                                //if (this.config.ViewData != null) { this.config.ViewData = new Dictionary<string, string>(this.config.ViewData, StringComparer.OrdinalIgnoreCase); }
                            }
                        }
                        if (this.config == null) { this.config = new DomainConfig(); }
                    }
                    return this.config;
                }
            }
        }

        private static DomainHelper Instance
        {
            get
            {
                var result = HttpContext.Current.Items["DomainHelper"] as DomainHelper;
                if (result == null)
                {
                    var url = HttpContext.Current.Request.Url;
                    result = new DomainHelper(url);
                    HttpContext.Current.Items["DomainHelper"] = result;
                }
                return result;
            }
        }

        public static bool IsLocal { get { return Instance.IsLocal; } }
        public static string FilePath { get { return Instance.DomainPath; } }

        private static string GetFilePath(string file)
        {
            var filePath = string.Empty;
            if (!string.IsNullOrWhiteSpace(file))
            {
                var wwwPath = FilePath;
                if (!string.IsNullOrWhiteSpace(wwwPath))
                {
                    var wwwFile = wwwPath + "/" + file;
                    var phyPath = HttpContext.Current.Server.MapPath(wwwFile);
                    if (File.Exists(phyPath))
                    {
                        filePath = wwwFile;
                    }
                }
            }
            return filePath;
        }

        /// <summary>
        /// 插入脚本文件
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        public static string InsertScript(string file)
        {
            var html = string.Empty;
            var wwwPath = GetFilePath(file);
            if (!string.IsNullOrWhiteSpace(wwwPath))
            {
                html = string.Format("<script type=\"text/javascript\" src=\"{0}\"></script>", wwwPath);
            }
            return html;
        }
        /// <summary>
        /// 插入样式文件
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        public static string InsertCss(string file)
        {
            var html = string.Empty;
            var wwwPath = GetFilePath(file);
            if (!string.IsNullOrWhiteSpace(wwwPath))
            {
                html = string.Format("<link rel=\"stylesheet\" type=\"text/css\" href=\"{0}\"></link>", wwwPath);
            }
            return html;
        }
        public static string GetViewPath(string file)
        {
            var path = GetFilePath(file);
            if (!string.IsNullOrWhiteSpace(path)) { path = ("~" + path); }
            return path;
        }

        public static string InsertDefaultScript()
        {
            var file = Instance.Config.ScriptFile;
            var str = InsertScript(file);
            return str;
        }
        public static string InsertDefaultCss()
        {
            var file = Instance.Config.CssFile;
            var str = InsertCss(file);
            return str;
        }

        /// <summary>
        /// 读取配置文件中的名称
        /// </summary>
        public static string Name { get { return Instance.Config.Name; } }
        /// <summary>
        /// 读取配置文件中的标题
        /// </summary>
        public static string Title { get { return Instance.Config.Title; } }
        /// <summary>
        /// 读取配置文件中的扩展数据
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static string GetData(string key)
        {
            var value = string.Empty;
            Instance.Config.ViewData.TryGetValue(key, out value);
            return value;
        }
    }
}